<?php

/**
 * CExportToCsv 
 * 导出CSV文件的类
 */
class CExportToCsv {
    /**
     * file 
     * 当前正在处理的临时文件名
     * 
     * @var string
     * @access private
     */
    private $file = '';

    /**
     * filePath 
     * 临时文件路径
     * 
     * @var string
     * @access private
     */
    private $filePath = '';

    /**
     * fileHandler 
     * 当前正在使用的临时文件指针
     * 
     * @var mixed
     * @access private
     */
    private $fileHandler;

    /**
     * toFile 
     * 最终输出的文件名
     * 
     * @var string
     * @access private
     */
    private $toFile = '';

    /**
     * field 
     * 待导出数据源数据对照表
     * 
     * @var array
     * @access private
     */
    private $field = array();

    public function __construct($file = NULL) {
        /**
         * 设置临时文件存储路径 
         */
        $this->filePath    = RUNTIME_PATH . '/Temp';
        $this->file        = empty($file) ?   tempnam($this->filePath, 'CSV' . date('YmdHi') . '_')   :   $file;
        $this->fileHandler = fopen($this->file, 'a');
    }

    /**
     * __destruct 
     * 析构函数
     * 
     * @access public
     * @return void
     */
    public function __destruct() {
        fclose($this->fileHandler);

        return true;

        if(!empty($this->file)) {
            @unlink($this->file);
        }
    }

    /**
     * __wakeup 
     * 
     * @access public
     * @return void
     */
    public function __wakeup() {
        $this->fileHandler = fopen($this->file, 'a');
    }


    /**
     * add 
     * 追加数据
     * 
     * @access public
     * @return void
     */
    public function add($row) {
        $r = array();

        /**
         * 过滤掉多余的数据 
         */
        foreach($this->field as $k => $v) {
            $r[$k] = isset($row[$k]) ? trim($row[$k]) : '';
        }

        $contents = implode("\t", $r) . "\n";
        $contents = iconv('utf-8', 'gbk', $contents);

        return fputs($this->fileHandler,  $contents);
    }


    /**
     * setFile 
     * 设置导出时的文件名
     * 
     * @access public
     * @return void
     */
    public function setFile($file) {
        $this->toFile = $file;

        return $this;
    }

    /**
     * setField 
     * 设置待导出的数据源中的字段对照表
     * 
     * @param mixed $field 
     * @access public
     * @return void
     */
    public function setField($field) {
        $this->field = $field;

        return $this;
    }

    /**
     * export 
     * 输出CSV文件
     * 
     * @access public
     * @return void
     */
    public function export() {
        if(empty($this->field) || empty($this->file)) {
            return false;                 
        }

        /**
         * 是否有多个临时文件 
         */
        $isMultiFile = count($this->fileSet) > 1   ?   true    :   false;
        $csvField    = implode("\t", array_values($this->field)). "\n";
        $tmpFile     = $this->toFile;

        header("Content-type:application/vnd.ms-excel");
        header("Content-Disposition:filename=$tmpFile.xls");   //此处变量不能用花括号包围，否则不能正常导出

        echo iconv('utf-8', 'gbk', $csvField);
        readfile($this->file);
    }

}

/**
 * CCsvFileRw 
 * CSV文件读写操作
 * 
 * @package 
 * @version $id$
 */
class CCsvFileRw {
    private $handler          =    NULL;    //文件句柄
    private $csvSpliter       =    "\t";    //列分隔符
    private $csvRowEndChar    =    "\n";    //行结束符
    private $rowMaxLength     =    100000; //行最大字符数

    public function __construct($handler) {
        $this->handler = $handler;
    }

    public function set($record) {
        $content = implode($this->csvSpliter, $record) . $this->csvRowEndChar;

        return fputs($this->handler, $content);
    }

    public function get() {
        if(!$row = fgets($this->handler, $this->rowMaxLength)) {
            return false;
        }

        if(!$record = explode($this->csvSpliter, trim($row))) {
            return false;
        }

        return $record;
    }

    public function rewind() {
        return rewind($this->handler);
    }

}

